﻿using Identitymodels;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace xiaodingmarket_service.Configurations
{
    public static class IdentitySetup
    {
        public static void AddIdentitySetup(this IServiceCollection services, IConfiguration configuration)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            //Microsoft.AspNetCore.Identit的相关配置
            //services.AddDefaultIdentity<IdentityUser>()
            //    .AddRoles<IdentityRole>()
            //    .AddEntityFrameworkStores<ApplicationDbContext>()
            //    .AddDefaultTokenProviders();

            //读取配置信息
            //var appSettingsSection = configuration.GetSection("TokenManagement");
            //services.Configure<TokenManagement>(appSettingsSection);

            //var appSettings = appSettingsSection.Get<TokenManagement>();
            //var key = Encoding.ASCII.GetBytes(appSettings.Secret);
            var section = configuration.GetSection("TokenManagement");
            //取密钥
            var symmetricKeyAsBase64 = section.GetSection("Secret").Value;
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = true;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = section.GetSection("Audience").Value,
                    ValidIssuer = section.GetSection("Issuer").Value,
                    ValidateIssuerSigningKey = true,//是否验证IssuerSigningKey 
                    IssuerSigningKey =signingKey,
                    ValidateIssuer = true,//是否验证Issuer
                    ValidateAudience = true,
                    
                    //RequireExpirationTime = true,//是否要求过期
                };
                x.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        //Token expired
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return Task.CompletedTask;
                    }
                };
            });
            //为生成器配置身份验证和授权服务。
            services.AddAuthorization(options =>
            {
                var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme);
                defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
                options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
            });
        }
        //策略授权
        public static void AddAuthSetup(this IServiceCollection services, IConfiguration configuration)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            //增加策略-- [Authorize(Policy="CanWriteCustomerData")]
            services.AddAuthorization(options =>
            {
                options.AddPolicy("CanReviewCommodity", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "Admin SuperAdmin")));
                options.AddPolicy("CanAppointAdmin", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "SuperAdmin")));
                options.AddPolicy("CanBasicoperation", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "OrdUser Admin SuperAdmin")));
            });
        }
    }
}
